package org.balthie.demo.jdk.util.concurrent.future.forkjoin;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;

public class DocumentSearchTask extends RecursiveTask<Integer>
{
    private static final long serialVersionUID = 1L;
    
    private String content[][];
    
    private int start, end;
    
    private String word;
    
    public DocumentSearchTask(String[][] content, int start, int end, String word)
    {
        super();
        this.content = content;
        this.start = start;
        this.end = end;
        this.word = word;
    }
    
    @Override
    protected Integer compute()
    {
        int result = 0;
        if(end - start < 5)
        {
            result = doProcessLines(content, start, end, word);
            System.out.println(MessageFormat.format("【{0}】doProcess【{1}】Lines【{2}】 appears 【{3}】times at【{4, time, HH:mm:ss:ms}】",
                    Thread.currentThread().getName(), end - start, word, result, new Date()));
        }
        else
        {
            int mid = (start + end) / 2;
            DocumentSearchTask task1 = new DocumentSearchTask(content, start, mid, word);
            DocumentSearchTask task2 = new DocumentSearchTask(content, mid, end, word);
            invokeAll(task1, task2);
            try
            {
                result = groupResults(task1.get(), task2.get());
            }
            catch (InterruptedException | ExecutionException e)
            {
                e.printStackTrace();
            }
        }
        return result;
    }
    
    private int groupResults(Integer integer1, Integer integer2)
    {
        return integer1 + integer2;
    }
    
    private int doProcessLines(String[][] document2, int start2, int end2, String word)
    {
        List<LineSearchTask> tasks = new ArrayList<LineSearchTask>();
        for(int i = start; i < end; i++)
        {
            LineSearchTask task = new LineSearchTask(document2[i], 0, document2[i].length, word);
            tasks.add(task);
        }
        
        invokeAll(tasks);
        int result = 0;
        for(LineSearchTask lineSearchTask : tasks)
        {
            try
            {
                result += lineSearchTask.get();
            }
            catch (InterruptedException | ExecutionException e)
            {
                e.printStackTrace();
            }
        }
        return result;
    }
}
